package chess;

import java.util.ArrayList;

public class AI {
    public static Move findBestMove(GameState gs, int depth) {
        ArrayList<Move> candidates = gs.getAllLegalMoves();
        boolean whiteToMove = gs.whiteToMove();
        Move best = candidates.get(0);
        int bestScore;
        if (whiteToMove) {
            bestScore = -20000;
        } else {
            bestScore = 20000;
        }
        for (Move move : candidates) {
            GameState next = new GameState(gs);
            next.makeMove(move);
            int score = evaluate(next, depth);
            if (isBetter(score, bestScore, whiteToMove)) {
                bestScore = score;
                best = move;
            }
        }
        return best;
    }

    /**
     * Evaluates the position, looking depth half-moves forward
     */
    public static int evaluate(GameState gs, int depth) {
        if (depth == 0) {
            return evaluateStill(gs);
        }

        ArrayList<Move> candidates = gs.getAllLegalMoves();
        boolean whiteToMove = gs.whiteToMove();
        int best;
        if (whiteToMove) {
            best = -20000;
        } else {
            best = 20000;
        }
        
        for (Move move : candidates) {
            //System.out.println("Now considering " + move);
            GameState next = new GameState(gs);
            next.makeMove(move);
            int score = evaluate(next, depth - 1);
            if (isBetter(score, best, whiteToMove)) {
                best = score;
            }
        }
        return best;
    }

    private static boolean isBetter(int a, int b, boolean something) {
        if (something) {
            return a > b;
        } else {
            return b > a;
        }
    }

    /**
     * Evaluates the position without "looking forward"
     * @param gs The GameState being evaluated
     * @return Positive if White is winning, negative if Black is winning.
     * Higher numbers mean White is winning more.
     */
    public static int evaluateStill(GameState gs) {
        Board b = gs.board();
        ArrayList<Square> white = b.white();
        ArrayList<Square> black = b.black();
        int score = 0;
        score += materialSum(white) - materialSum(black);
        return score;
    }

    /**
     * Sums the amount of material on a side, by conventional count
     * @param side ArrayList of the squares the pieces are on
     * @return Sum of the values of the pieces (Pawn = 1, Knight = 3, etc.)
     */
    private static int materialSum(ArrayList<Square> side) {
        int sum = 0;
        Piece p;
        for (Square s : side) {
            p = s.piece();
            if (p.isPawn()) {
                sum += 1;
            } else if (p.isRook()) {
                sum += 5;
            } else if (p.isQueen()) {
                sum += 9;
            } else if (p.isKing()) {
                sum += 10000;
            } else {
                sum += 3;
            }
        }
        return sum;
    }
}
